package flexulous.model;

import java.util.*;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;


public class FlexulousTarget extends Observable
{
	
	private String name;
	private String source;
	private String output;
    private boolean enabled;
    private boolean debug = false;
    private ArrayList<String> configFiles;
    
    public static final int DIRTY = 1;
    public static final int CHANGED = 2;
    
    
    
    /**
	 * Returns the value of debug.
	 */
	public boolean getDebug()
	{
		return debug;
	}

	/**
	 * Sets the value of debug.
	 * @param debug The value to assign debug.
	 */
	public void setDebug(boolean debug)
	{
		this.debug = debug;
	}

	/**
	 * Returns the value of configFiles.
	 */
	public ArrayList<String> getConfigFiles()
	{
		return configFiles;
	}
	
	
	public FlexulousTarget(String name, String source, String output)
	{
		this.name = name;
		this.source = source;
		this.output = output;
		enabled = false;
		configFiles = new ArrayList<String>();
	}
	
	/**
	 * Returns the value of name.
	 */
	public String getName()
	{
		return name;
	}

	/**
	 * Sets the value of name.
	 * @param name The value to assign name.
	 */
	public void setName(String name)
	{
		this.name = name;
	}

	/**
	 * Returns the value of source.
	 */
	public String getSource()
	{
		return source;
	}

	/**
	 * Sets the value of the source file to compile.
	 * @param source The value to assign source.
	 */
	public void setSource(String source)
	{
		this.source = source;
	}

	/**
	 * Returns the value of output.
	 */
	public String getOutput()
	{
		return output;
	}

	/**
	 * Sets the value of output.
	 * @param output The value to assign output.
	 */
	public void setOutput(String output)
	{
		this.output = output;
	}
    
    public boolean isEnabled() {
        return enabled;
    }
    
    public void setEnabled(boolean value) {
        enabled = value;
    }
	
    public void notifyTargetDirty()
    {
    	setChanged();
    	notifyObservers(DIRTY);
    }
    
    public void notifyTargetChanged()
    {
    	setChanged();
    	notifyObservers(CHANGED);
    	
    }
    
	public Element toXML(Document dom)
	{
		Element e = dom.createElement("target");
		Element eName = dom.createElement("name");
		Element eSource = dom.createElement("source");
		Element eOutput = dom.createElement("output");
		Element eEnabled = dom.createElement("enabled");
		Element eDebug = dom.createElement("debug");
		
		
		Text tName = dom.createTextNode(name);
		Text tSource = dom.createTextNode(source);
		Text tOutput = dom.createTextNode(output);
		Text tEnabled = dom.createTextNode(enabled ? "true" : "false");
		Text tDebug = dom.createTextNode(debug ? "true" : "false");
		
		eName.appendChild(tName);
		eSource.appendChild(tSource);
		eOutput.appendChild(tOutput);
		eEnabled.appendChild(tEnabled);
		eDebug.appendChild(tDebug);
		e.appendChild(eName);
		e.appendChild(eSource);
		e.appendChild(eOutput);
		e.appendChild(eEnabled);
		e.appendChild(eDebug);
		
		for(Iterator iter = configFiles.iterator(); iter.hasNext();){
		  String item = (String)iter.next();
		  Element eConfigFile = dom.createElement("configfile");
		  Text tConfigFile = dom.createTextNode(item);
		  eConfigFile.appendChild(tConfigFile);
		  e.appendChild(eConfigFile);
		}
		return e;
	}
	
	public static FlexulousTarget fromXML(Element e)
	{
			String name = getTextValue(e, "name");
			String source = getTextValue(e, "source");
			String output = getTextValue(e, "output");
			Boolean enabled = getBooleanValue(e, "enabled");
			Boolean debug = getBooleanValue(e, "debug");
			
			
			FlexulousTarget t = new FlexulousTarget(name, source, output);
			t.enabled = enabled;
			t.debug = debug;
			
			//Get config files.
			NodeList nl = e.getElementsByTagName("configfile");
			if(nl!=null && nl.getLength() > 0){
				for(int i=0;i<nl.getLength();i++){
					Element el = (Element)nl.item(0);
					String textVal = el.getFirstChild().getNodeValue();
					t.configFiles.add(textVal);
				}
			}
			
			
			return t;
	}
	
	
	/**
	 * I take a xml element and the tag name, look for the tag and get
	 * the text content 
	 * i.e for <employee><name>John</name></employee> xml snippet if
	 * the Element points to employee node and tagName is name I will return John  
	 * @param ele
	 * @param tagName
	 * @return
	 */
	public static String getTextValue(Element ele, String tagName) {
		String textVal = null;
		NodeList nl = ele.getElementsByTagName(tagName);
		if(nl != null && nl.getLength() > 0) {
			Element el = (Element)nl.item(0);
			textVal = el.getFirstChild().getNodeValue();
		}

		return textVal;
	}

	
	/**
	 * Calls getTextValue and returns a int value
	 * @param ele
	 * @param tagName
	 * @return
	 */
	public static int getIntValue(Element ele, String tagName) {
		//in production application you would catch the exception
		return Integer.parseInt(getTextValue(ele,tagName));
	}
	
	
	/**
	 * Calls getTextValue and returns a boolean value
	 * @param ele
	 * @param tagName
	 * @return
	 */
	public static Boolean getBooleanValue(Element ele, String tagName) {
		//in production application you would catch the exception
		return Boolean.parseBoolean(getTextValue(ele,tagName));
	}
	
	
	
}
